import hashlib
import os
import random
import json
import logging
from django.http import JsonResponse
from django.shortcuts import render, redirect
from django.views import View
from django.views.decorators.clickjacking import xframe_options_exempt

from dashboard import k8s
from .details import DeploymentDetailsInfo
from .k8s import auth_check, NamespaceApi, NodeApi, PersistenVolumesApi, DeploymentApi, DaemonsetApi, \
    StatefulsetApi, PodApi, ServiceApi, IngressApi, PersistentVolumeClaimsApi, ConfigmapApi, SecretsApi, K8sApi, \
    ContainerApi, memory_format, cpu_format


# Create your views here.


@k8s.self_login_required
def index(request):
    namespace_all = NamespaceApi(request).get()
    node_all = NodeApi(request).get()
    pod_all = PodApi(request).get()
    deployment_all = DeploymentApi(request).get()
    daemonset_all = DaemonsetApi(request).get()
    namespace_count = len(namespace_all['data'])
    node_status = {}
    node_schedulable = {}
    node_capacity_memory = 0
    node_capacity_cpu = 0
    node_allocatable_cpu = 0
    node_allocatable_memory = 0
    node_resource = []
    for data in node_all['data']:
        # print(data)
        # 计算node节点存活状态
        if data['status'] in node_status.keys():
            node_status[data['status']] += 1
        else:
            node_status[data['status']] = 1
        # 计算node节点可调度状态
        if data['ready'] in node_schedulable.keys():
            node_schedulable[data['ready']] += 1
        else:
            node_schedulable[data['ready']] = 1

        # 计算总cpu
        node_capacity_cpu += int(data['capacity_cpu'])
        node_allocatable_cpu += int(data['cpu'])
        # 计算总内存与可分配内存
        allocatable_memory = memory_format(data['memory'])
        capacity_memory = memory_format(data['capacity_memory'])
        node_capacity_memory += capacity_memory
        node_allocatable_memory += allocatable_memory
        # 计算每个Node节点使用的资源
        node_requests_cpu = 0
        node_requests_memory = 0
        node_pod_num = 0
        for pod in pod_all['data']:
            if pod['node'] == data['name']:
                node_requests_cpu += pod['requests_cpu']
                node_requests_memory += pod['requests_memory']
                node_pod_num += 1

        node_resource.append({
            "node_requests_cpu": cpu_format(node_requests_cpu),
            "node_requests_memory": memory_format(node_requests_memory),
            "node_pod_num": node_pod_num,
            "node_cpu": data['capacity_cpu'],
            "node_memory": data['capacity_memory'],
            "pod": data['pods'],
            "status": data['status'],
            "ip": data['ip'],
            "name": data['name'],
            "cpu_percentage": str(int((float(node_requests_cpu) / float(data['capacity_cpu'])) * 100)) + '%',
            "memory_percentage": str(int((float(node_requests_memory) / float(data['capacity_memory'])) * 100)) + '%',
            "pod_percentage": str(int(int(node_pod_num) / int(data['pods']) * 100)) + '%'
        })
    # pod 总占用资源计算
    pod_requests_cpu = 0
    pod_requests_memory = 0
    for pod in pod_all['data']:
        pod_requests_cpu += pod['requests_cpu']
        pod_requests_memory += pod['requests_memory']

    node_info = json.dumps({
        "status": node_status,
        "schedulable": node_schedulable,
        "capacity_cpu": node_capacity_cpu,
        "capacity_memory": round(node_capacity_memory, 2),
        "allocatable_memory": round(node_allocatable_memory, 2),
        "allocatable_cpu": node_allocatable_cpu,
        "pod_requests_cpu": int(pod_requests_cpu),
        "pod_requests_memory": int(pod_requests_memory)
    })
    workload_info = {
        "namespace_count": namespace_count,
        "pod_count": len(pod_all['data']),
        "deployment_count": len(deployment_all['data']),
        "daemonset_count": len(daemonset_all['data'])
    }
    return render(request, "index.html", {"node": node_info, "node_all": node_resource, "workload": workload_info})


def login(request):
    if request.method == "GET":
        return render(request, "login.html")
    elif request.method == "POST":
        if request.POST.get('type') == 'token':
            logging.debug('token方式登录')
            token = request.POST.get('token')
            if auth_check('token', token):
                request.session['is_login'] = True
                request.session['auth_type'] = 'token'
                request.session['token'] = token
                code = 0
                msg = 'token认证成功'
            else:
                code = 1
                msg = 'token认证失败'
        elif request.POST.get('type') == 'kubeconfig':
            logging.debug('kubeconfig方式登录')
            file_obj = request.FILES.get('file')
            random_str = hashlib.md5(str(random.random()).encode()).hexdigest()
            file_path = os.path.join('config', random_str)
            try:
                with open(file_path, 'w', encoding='utf8') as f:
                    data = file_obj.read().decode()
                    f.write(data)
            except Exception as e:
                print('file read error: %s' % e)
                code = 1
                msg = '文件无效'

            if auth_check('kubeconfig', random_str):
                code = 0
                msg = '认证成功'
                request.session['is_login'] = True
                request.session['auth_type'] = 'kubeconfig'
                request.session['token'] = random_str
            else:
                code = 1
                msg = '读取失败'

        res = {'msg': msg, 'code': code}
        return JsonResponse(res)


def logout(request):
    request.session.flush()
    return redirect(login)


class NamespaceApiView(View):

    def get(self, request):
        api = NamespaceApi(request)
        return JsonResponse(api.get())

    def delete(self, request):
        api = NamespaceApi(request)
        return JsonResponse(api.delete())

    def post(self, request):
        api = NamespaceApi(request)
        return JsonResponse(api.post())


class NodeApiView(View):

    def get(self, request):
        api = NodeApi(request)
        return JsonResponse(api.get())


class PersistenVolumeApiView(View):

    def get(self, request):
        api = PersistenVolumesApi(request)
        return JsonResponse(api.get())

    def delete(self, request):
        api = PersistenVolumesApi(request)
        return JsonResponse(api.delete())

    def post(self, request):
        api = PersistenVolumesApi(request)
        return JsonResponse(api.post())


class DeploymentDetailsApiView(View):

    def get(self, request):
        api = DeploymentDetailsInfo(request)
        data = api.history_info()
        return JsonResponse(data)


class DeploymentApiView(View):

    def get(self, request):
        api = DeploymentApi(request)
        return JsonResponse(api.get())

    def delete(self, request):
        api = DeploymentApi(request)
        return JsonResponse(api.delete())

    def post(self, request):
        api = DeploymentApi(request)
        return JsonResponse(api.post())

    def put(self, request):
        api = DeploymentApi(request)
        return JsonResponse(api.put())


class DaemonsetApiView(View):

    def get(self, request):
        api = DaemonsetApi(request)
        return JsonResponse(api.get())

    def delete(self, request):
        api = DaemonsetApi(request)
        return JsonResponse(api.delete())

    def post(self, request):
        api = DaemonsetApi(request)
        return JsonResponse(api.post())


class StatefulsetApiView(View):

    def get(self, request):
        api = StatefulsetApi(request)
        return JsonResponse(api.get())

    def delete(self, request):
        api = StatefulsetApi(request)
        return JsonResponse(api.delete())

    def post(self, request):
        api = StatefulsetApi(request)
        return JsonResponse(api.post())


class PodApiView(View):

    def get(self, request):
        api = PodApi(request)
        return JsonResponse(api.get())

    def delete(self, request):
        api = PodApi(request)
        return JsonResponse(api.delete())

    def post(self, request):
        api = PodApi(request)
        return JsonResponse(api.post())


class ContainerApiView(View):

    def get(self, request):
        api = ContainerApi(request)
        return JsonResponse(api.get())


class ServiceApiView(View):

    def get(self, request):
        api = ServiceApi(request)
        return JsonResponse(api.get())

    def delete(self, request):
        api = ServiceApi(request)
        return JsonResponse(api.delete())

    def post(self, request):
        api = ServiceApi(request)
        return JsonResponse(api.post())


class IngressApiView(View):

    def get(self, request):
        api = IngressApi(request)
        return JsonResponse(api.get())

    def delete(self, request):
        api = IngressApi(request)
        return JsonResponse(api.delete())

    def post(self, request):
        api = IngressApi(request)
        return JsonResponse(api.post())


class PersistentVolumeClaimsApiView(View):

    def get(self, request):
        api = PersistentVolumeClaimsApi(request)
        return JsonResponse(api.get())

    def delete(self, request):
        api = PersistentVolumeClaimsApi(request)
        return JsonResponse(api.delete())


class ConfigmapApiView(View):

    def get(self, request):
        api = ConfigmapApi(request)
        return JsonResponse(api.get())

    def delete(self, request):
        api = ConfigmapApi(request)
        return JsonResponse(api.delete())

    def post(self, request):
        api = ConfigmapApi(request)
        return JsonResponse(api.post())


class SecretsApiView(View):

    def get(self, request):
        api = SecretsApi(request)
        return JsonResponse(api.get())

    def delete(self, request):
        api = SecretsApi(request)
        return JsonResponse(api.delete())

    def post(self, request):
        api = SecretsApi(request)
        return JsonResponse(api.post())


class ExportResourceView(View):

    def get(self, request):
        _auth = K8sApi(request=request)
        namespace = request.GET.get('namespace', None)
        resource = request.GET.get('resource', None)
        name = request.GET.get('name', None)
        app_list = ['deployment', 'daemon_set', 'stateful_set', 'replica_set']
        core_list = ['pod', 'service', 'persistent_volume_claim', 'secret', 'config_map', 'node', 'namespace',
                     'persistent_volume']
        network_list = ['ingress']
        code = 1
        msg = '数据获取失败'
        data = {}
        if resource in app_list:
            res = _auth.read_resource(api_name='client.AppsV1Api()', name=name, namespace=namespace, resource=resource)
            return JsonResponse(res)
        elif resource in core_list:
            res = _auth.read_resource(api_name='client.CoreV1Api()', name=name, namespace=namespace, resource=resource)
            return JsonResponse(res)
        elif resource in network_list:
            res = _auth.read_resource(api_name='client.NetworkingV1Api()', name=name, namespace=namespace,
                                      resource=resource)
            return JsonResponse(res)

        return JsonResponse({'code': code, 'msg': msg, 'data': data})


@xframe_options_exempt
def ace_edit(request):
    data = {'name': request.GET.get('name'), 'namespace': request.GET.get('namespace'),
            'resource': request.GET.get('resource')}
    return render(request, 'ace-edit.html', {'data': data})
